﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 状态机类
/// </summary>
public class ControllableStateMachine : StateMachine
{
    /// <summary>
    /// 作为保留状态的标志
    /// </summary>
    public static ControllableObjectState remainState;

    /// <summary>
    /// 作为回到前一个状态的标志
    /// </summary>
    public static ControllableObjectState previousState;

    private GameObject m_gameObject;

    /// <summary>
    /// 下推自动机
    /// </summary>
    protected MyStack<ControllableObjectState> m_stateStack = new MyStack<ControllableObjectState>();

    /// <summary>
    /// 起始状态并且作为暂时变量
    /// </summary>
    [SerializeField] private ControllableObjectState m_startState;

    // Use this for initialization
    void Start()
    {
        m_startState.EnterState(m_gameObject);
        m_stateStack.Push(m_startState);

        m_gameObject = this.gameObject;

        EventMgr.AddEventListener(GameTypeDefine.EVENT_ID.BUTTON_DOWN, ButtonDown);
        EventMgr.AddEventListener(GameTypeDefine.EVENT_ID.BUTTON_UP, ButtonUp);
        EventMgr.AddEventListener(GameTypeDefine.EVENT_ID.BUTTON_PRESSED, ButtonPressed);

        if (null == remainState && null == previousState)
        {
            remainState = ScriptableObject.CreateInstance<ControllableObjectState>();
            previousState = ScriptableObject.CreateInstance<ControllableObjectState>();
        }
    }

    // Update is called once per frame
    void Update()
    {
        m_stateStack.Peek().StateUpdate(m_gameObject);
    }

    private void ButtonDown(GameTypeDefine.EVENT_ID id, MyEventArgs args)
    {
        for (int i = 0, length = m_stateStack.Count - 1; i < length; i++)
        {
            m_stateStack.GetAt(i).ButtonDown((ButtonEventArgs)args, m_gameObject);
        }

        m_startState = m_stateStack.Peek().ButtonDown((ButtonEventArgs)args, m_gameObject);

        ChangeState();
    }

    private void ButtonUp(GameTypeDefine.EVENT_ID id, MyEventArgs args)
    {
        for (int i = 0, length = m_stateStack.Count - 1; i < length; i++)
        {
            m_stateStack.GetAt(i).ButtonUp((ButtonEventArgs)args, m_gameObject);
        }

        m_startState = m_stateStack.Peek().ButtonUp((ButtonEventArgs)args, m_gameObject);

        ChangeState();
    }

    private void ButtonPressed(GameTypeDefine.EVENT_ID id, MyEventArgs args)
    {
        for (int i = 0, length = m_stateStack.Count - 1; i < length; i++)
        {
            m_stateStack.GetAt(i).ButtonPressed((ButtonEventArgs)args, m_gameObject);
        }

        m_startState = m_stateStack.Peek().ButtonPressed((ButtonEventArgs)args, m_gameObject);

        ChangeState();
    }

    /// <summary>
    /// 改变状态
    /// </summary>
    private void ChangeState()
    {
        //保留状态
        if (remainState.Equals(m_startState))
        {
            return;
        }

        //回到上一状态
        if (previousState.Equals(m_startState) && m_stateStack.Count > 1)
        {
            m_stateStack.Peek().ExitState(m_gameObject);

            m_stateStack.Pop();

            while (m_stateStack.Peek().isNeedToPop)
            {
                m_stateStack.Peek().ExitState(m_gameObject);

                m_stateStack.Pop();
            }

            m_stateStack.Peek().isAtTop = true;

            return;
        }

        ///如果存在指定状态则弹出至指定状态
        if (m_stateStack.Contains(m_startState))
        {
            while (m_stateStack.Count != 0)
            {
                if (m_startState.Equals(m_stateStack.Peek()))
                {
                    break;
                }

                m_stateStack.Peek().ExitState(m_gameObject);

                m_stateStack.Pop();
            }

            m_stateStack.Peek().isAtTop = true;
        }
        else
        {
            m_startState.EnterState(m_gameObject);

            m_stateStack.Push(m_startState);
        }
    }

    /// <summary>
    /// 获取隐蔽状态
    /// </summary>
    /// <returns></returns>
    //public GameTypeDefine.HIDE_STATE GetHideState()
    //{
    //return m_hideState;
    //}
}
